home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
lang
/
fpcsrc.lha
/
fpc
/
compiler
/
asmutils.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-09-24
|
60KB
|
1,698 lines
{
$Id: asmutils.pas,v 1.1.1.1 1998/03/25 11:18:12 root Exp $
Copyright (c) 1998 Carl Eric Codere
This unit implements some support routines for assembler parsing
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**********************************************************************}
Unit AsmUtils;
{*************************************************************************}
{ This unit implements some objects as well as utilities which will be }
{ used by all inline assembler parsers (non-processor specific). }
{ }
{ Main routines/objects herein: }
{ o Object TExprParse is a simple expression parser to resolve assembler }
{ expressions. (Based generally on some code by Thai Tran from SWAG). }
{ o Object TInstruction is a simple object used for instructions }
{ o Record TOperand is a simple record used to store information on }
{ each operand. }
{ o String conversion routines from octal,binary and hex to decimal. }
{ o A linked list object/record for local labels }
{ o Routines for retrieving symbols (local and global) }
{ o Object for a linked list of strings (with duplicate strings not }
{ allowed). }
{ o Non-processor dependant routines for adding instructions to the }
{ instruction list. }
{*************************************************************************}
{--------------------------------------------------------------------}
{ LEFT TO DO: }
{ o Fix the remaining bugs in the expression parser, such as with }
{ 4+-3 }
{ o Add support for local typed constants search. }
{ o Add support for private/protected fields in method assembler }
{ routines. }
{--------------------------------------------------------------------}
Interface
Uses
symtable,aasm,hcodegen,verbose,systems,globals,files,strings,
cobjects,
{$ifdef i386}
i386;
{$endif}
{$ifdef m68k}
m68k;
{$endif}
Const
RPNMax = 10; { I think you only need 4, but just to be safe }
OpMax = 25;
maxoperands = 3; { Maximum operands for assembler instructions }
Type
{---------------------------------------------------------------------}
{ Label Management types }
{---------------------------------------------------------------------}
PAsmLabel = ^TAsmLabel;
PString = ^String;
{ Each local label has this structure associated with it }
TAsmLabel = record
name: PString; { pointer to a pascal string name of label }
lab: PLabel; { pointer to a label as defined in FPC }
emitted: boolean; { as the label itself been emitted ? }
next: PAsmLabel; { next node }
end;
TAsmLabelList = Object
public
First: PAsmLabel;
Constructor Init;
Destructor Done;
Procedure Insert(s:string; lab: PLabel; emitted: boolean);
Function Search(const s: string): PAsmLabel;
private
Last: PAsmLabel;
Function NewPasStr(s:string): PString;
end;
{---------------------------------------------------------------------}
{ Instruction management types }
{---------------------------------------------------------------------}
toperandtype = (OPR_NONE,OPR_REFERENCE,OPR_CONSTANT,OPR_REGISTER,OPR_LABINSTR,
OPR_REGLIST);
{ When the TReference field isintvalue = TRUE }
{ then offset points to an ABSOLUTE address }
{ otherwise isintvalue should always be false }
{ Special cases: }
{ For the M68k Target, size is UNUSED, the }
{ opcode determines the size of the }
{ instruction. }
{ DIVS/DIVU/MULS/MULU of the form dn,dn:dn }
{ is stored as three operands!! }
{ Each instruction operand can be of this type }
TOperand = record
size: topsize;
opinfo: longint; { ao_xxxx flags }
case operandtype:toperandtype of
{ the size of the opr_none field should be at least equal to each }
{ other field as to facilitate initialization. }
OPR_NONE: (l: array[1..sizeof(treference)] of byte);
OPR_REFERENCE: (ref:treference);
OPR_CONSTANT: (val: longint);
OPR_REGISTER: (reg:tregister);
OPR_LABINSTR: (hl: plabel);
{ Register list such as in the movem instruction }
OPR_REGLIST: (list: set of tregister);
end;
TInstruction = object
public
operands: array[1..maxoperands] of TOperand;
{ if numops = zero, a size may still be valid in operands[1] }
{ it still should be checked. }
numops: byte;
{ set to TRUE if the instruction is labeled. }
labeled: boolean;
{ This is used for instructions such A_CMPSB... etc, to determine }
{ the size of the instruction. }
stropsize: topsize;
procedure init;
{ sets up the prefix field with the instruction pointed to in s }
procedure addprefix(tok: tasmop);
{ sets up the instruction with the instruction pointed to in s }
procedure addinstr(tok: tasmop);
{ get the current instruction of this object }
function getinstruction: tasmop;
{ get the current prefix of this instruction }
function getprefix: tasmop;
private
prefix: tasmop;
instruction: tasmop;
end;
{---------------------------------------------------------------------}
{ Expression parser types }
{---------------------------------------------------------------------}
{ expression parser error codes }
texpr_error =
(zero_divide, { divide by zero. }
stack_overflow, { stack overflow. }
stack_underflow, { stack underflow. }
invalid_number, { invalid conversion }
invalid_op); { invalid operator }
TExprOperator = record
ch: char; { operator }
is_prefix: boolean; { was it a prefix, possible prefixes are +,- and not }
end;
String15 = String[15];
{**********************************************************************}
{ The following operators are supported: }
{ '+' : addition }
{ '-' : subtraction }
{ '*' : multiplication }
{ '/' : modulo division }
{ '^' : exclusive or }
{ '<' : shift left }
{ '>' : shift right }
{ '&' : bitwise and }
{ '|' : bitwise or }
{ '~'